﻿//-----------------------------------------------------------------------
// <copyright file="TileGenerator.cs" company="Microsoft Corporation">
//     Copyright Microsoft Corporation. All Rights Reserved. This code released under the terms of the Microsoft Public License (MS-PL, http://opensource.org/licenses/ms-pl.html.) This is sample code only, do not use in production environments.
// </copyright>
//-----------------------------------------------------------------------

namespace Microsoft.ALMRangers.VsarTreasureMap.WindowsStoreApp.LiveTile
{
    using System;
    using System.Globalization;
    using System.Xml.Linq;
    using Windows.Data.Xml.Dom;
    using Windows.UI.Notifications;

    /// <summary>
    /// Used to generate files
    /// </summary>
    internal static class TileGenerator
    {
#if DEBUG
        /// <summary>
        /// Gets or sets the test wide.
        /// </summary>
        /// <value>The test wide.</value>
        public static XDocument TestWide { get; set; }

        /// <summary>
        /// Gets or sets the test square.
        /// </summary>
        /// <value>The test square.</value>
        public static XDocument TestSquare { get; set; }

        /// <summary>
        /// This is only used for unit tests
        /// </summary>
        /// <param name="header">The header for the tile</param>
        /// <param name="content">The content for the tile</param>
        public static void GenerateNewsTileTestAccessor(string header, string content)
        {
            content = content.Trim().Trim('\n');
            if (content.Length > 200)
            {
                content = content.Substring(0, 200);
            }

            header = "News: " + header;

            TestWide = WrapTileContent("TileWideText09", TextElement("1", header), TextElement("2", content));
            TestSquare = WrapTileContent("TileSquareText02", TextElement("1", header), TextElement("2", content));
        }
#endif

        /// <summary>
        /// Generates the news tile.
        /// </summary>
        /// <param name="header">The header.</param>
        /// <param name="content">The content.</param>
        public static void GenerateNewsTile(string header, string content)
        {
            content = content.Trim().Trim('\n');
            if (content.Length > 200)
            {
                content = content.Substring(0, 200);
            }

            header = "News: " + header;

            var wide = WrapTileContent("TileWideText09", TextElement("1", header), TextElement("2", content));
            var square = WrapTileContent("TileSquareText02", TextElement("1", header), TextElement("2", content));

            UpdateTiles(CreateTileNotification(square, Guid.NewGuid().ToString("B").Substring(0, 10)), CreateTileNotification(wide, Guid.NewGuid().ToString("B").Substring(0, 10)));
        }

        /// <summary>
        /// Generates the percentage tile.
        /// </summary>
        public static void GeneratePercentageTile()
        {
            var percent = (double)App.Database.StatusManager.CompletedProjectCount / (double)App.Database.StatusManager.ProjectCount;
            var workshopPercent = GetPercent(5);
            var guidancePercent = GetPercent(3);
            var quickIntroPercent = GetPercent(2);
            var preparePercent = GetPercent(1);
            var toolingPercent = GetPercent(4);

            var wide = WrapTileContent(
                "TileWideText02",
                TextElement("1", string.Format(CultureInfo.CurrentUICulture, "{0:P0} Complete", percent)),
                TextElement("2", string.Format(CultureInfo.CurrentUICulture, "{0:P0} Workshops", workshopPercent)),
                TextElement("3", string.Format(CultureInfo.CurrentUICulture, "{0:P0} Guidance", guidancePercent)),
                TextElement("4", string.Format(CultureInfo.CurrentUICulture, "{0:P0} Quick Intro", quickIntroPercent)),
                TextElement("5", string.Format(CultureInfo.CurrentUICulture, "{0:P0} Prepare", preparePercent)),
                TextElement("6", string.Format(CultureInfo.CurrentUICulture, "{0:P0} Tooling", toolingPercent)),
                TextElement("7", string.Empty),
                TextElement("8", string.Empty),
                TextElement("9", string.Empty));

            var square = WrapTileContent(
                "TileSquareBlock", TextElement("1", (percent * 100).ToString("F0", CultureInfo.CurrentUICulture)), TextElement("2", "% complete"));

            UpdateTiles(CreateTileNotification(square, "percentageSquare"), CreateTileNotification(wide, "percentageWide"));
        }

        /// <summary>
        /// Creates the tile notification.
        /// </summary>
        /// <param name="xml">The tile XML.</param>
        /// <param name="id">The tile id.</param>
        /// <returns>A TileNotification.</returns>
        private static TileNotification CreateTileNotification(XDocument xml, string id)
        {
            var result = new TileNotification(XmlContent(xml));
            result.Tag = id;
            return result;
        }

        /// <summary>
        /// Gets the percentage for a specified category.
        /// </summary>
        /// <param name="category">The category.</param>
        /// <returns>The percentage completed.</returns>
        private static double GetPercent(int category)
        {
            return (double)App.Database.StatusManager.GetCompletedProjectCount(category) / (double)App.Database.StatusManager.GetProjectCount(category);
        }

        /// <summary>
        /// Creates a XElement from an ID and content.
        /// </summary>
        /// <param name="id">The id.</param>
        /// <param name="content">The content.</param>
        /// <returns>An XElement.</returns>
        private static XElement TextElement(string id, string content)
        {
            return new XElement("text", new XAttribute("id", id), content);
        }

        /// <summary>
        /// Updates the tiles.
        /// </summary>
        /// <param name="squareTile">The square tile.</param>
        /// <param name="wideTile">The wide tile.</param>
        private static void UpdateTiles(TileNotification squareTile, TileNotification wideTile)
        {
            App.TileUpdater.Update(squareTile);
            App.TileUpdater.Update(wideTile);
        }

        /// <summary>
        /// Wraps the contents of a tile into a XDocument.
        /// </summary>
        /// <param name="template">The template.</param>
        /// <param name="content">The content.</param>
        /// <returns>A XDocument which contains the content of a tile.</returns>
        private static XDocument WrapTileContent(string template, params XElement[] content)
        {
            var doc = new XDocument(
                new XElement(
                    "tile",
                    new XElement(
                        "visual",
                        new XElement(
                            "binding",
                            new XAttribute("template", template),
                            new XAttribute("branding", "name"),
                        content))));

            return doc;
        }

        /// <summary>
        /// Converts a XDocument into a XmlDocument.
        /// </summary>
        /// <param name="document">The XDocument.</param>
        /// <returns>A XmlDocument version of XDocument.</returns>
        private static XmlDocument XmlContent(XDocument document)
        {
            var result = new XmlDocument();
            result.LoadXml(document.ToString());
            return result;
        }
    }
}